const {getDmg,reduceResistanceK,lvSuppressK,objValueAdd } = require("../libs/apis.js")
const WEAPONS = require("./weapons.js");

const CLIPDATA_TYPE = {
    max:{
        fixedhp: 298.75,
        fixedAtt: 19.45,
        fixdefence: 23.15,
        reaction : 23.31,
        attRate: 5.83, 
        hpRate: 5.83, 
        criticalRate: 3.89,
        criticalStrike: 7.77,
        defRate: 7.29,
        charging: 6.48
    },
    mid:{
        fixedhp: 253.94,   // 209.13  239   268.88   298.75
        fixdefence: 19.675, // 16.2   18.52  20.83  23.15
        fixedAtt: 16.535,   //  13.62   15.56   17.51  19.45
        reaction : 19.815,  // 16.32   18.65  20.98  23.31
        attRate: 4.955,  // 4.08  4.66  5.25  5.83
        hpRate: 4.955,   // 4.08  4.66  5.25  5.83
        criticalRate: 3.305,   //  2.72  3.11   3.5   3.89
        criticalStrike: 6.605,  //  5.44  6.22  6.99  7.77
        defRate: 6.195,   //  5.1  5.83  6.56   7.29
        charging: 5.505  //  4.53   5.18   5.83   6.48
    }
}

const CLIPDATA = CLIPDATA_TYPE.mid

const CONFIG = {
    chance: 4,
    your_lv: 90,
    enemy_lv: 90,
    clips_main: {
        fixedHp: 4780,
        fixedAtt:311,
        hpRate: 46.6 * 3,
        // dmgRate: 46.6,
        // criticalStrike: 62.2,
    },
    clips_initial: [ 
        ["charging", "hpRate", "criticalRate", "criticalStrike"],
        ["charging", "hpRate", "criticalRate", "criticalStrike"],
        ["hpRate", "charging", "criticalRate", "criticalStrike"],
        ["charging", "hpRate", "criticalRate", "criticalStrike"],
        ["reaction", "charging", "criticalStrike", "criticalRate"]
    ],
    reactionK : 1.5,
    reactionDmgAdd: 0,
    buffs: [  
        { eDmg: 70},  // e 套
        // { jk:40, dmgRate: 40} , // 万叶
        { hpRate: 25 } , // 双水
        // { hpRate: 20 } , // 水单手剑20hp
        // { jk: 20, dmgRate: 35 }, // 攀岩钟离
    ]
}

let charaters = {
    units : {
        name: "芙芙", 
        reaction: 0,
        dmgZhi: 0,
        dmgRate:0,
        charging: 100,
        jk:0,
        defRate: 0,
        eDmg:0,
        defence: 576,
        weapontype: "sword", // sword sword2 qiang magic bow
        hp:15307,
        base: 243.96,    
        criticalRate: 5+38.4/2,    
        criticalStrike: 50,
        skills: {
            a: [
                function(data){},
            ]
        }
    },
}

let tmp = {}
CONFIG.clips_initial.forEach(item => {
    item.forEach(item2 => {
        if(tmp[item2]) {
            tmp[item2] += 1
        } else {
            tmp[item2] = 1
        }
    })
})

/*
   满气氛值下  4个队友都50%以上血(1.4倍召唤物伤害)  
   0.8275862068965517 1.34453781512605 0.75
   e:                  乌瑟勋爵(2.4%)     海薇玛夫人(1.6%)     谢贝蕾小姐(3.6%)     回血召唤物
   lv10:  14.16%hp       10.73%/2.9s       5.82%/1.19s         14.92%/4.8s      8.64%hp+1016.97
   lv13:  16.71%hp       12.67%/2.9s       6.87%/1.19s         17.61%/4.8s      8.6%hp + 1182.63

   q: 上限300气氛值
   lv10:   20.53%hp     0.25%
   lv13:   24.24%hp     0.31%

   天赋(4w血)叠满 1000->(0.7/0.4)   最高28% e增伤 16% 降低e回血间隔

   命座 
    1 开q自动获得150气氛值 上限+100
    2 q气氛值获得提升250% 气氛值超过上限的部分 每点+0.35%hp 最高 140%hp
    3 q + 3
    4 召唤物命中给芙芙 4 能量 cd 5s
    5 e + 3
    6 e后10s 芙芙获得水元素附着 伤害值提升 15%hp 荒根据芙4%hp全队回血 芒再次附加20%hp伤害值 全队hp-1% 该效果最多触发7次


    有双水
                            乌瑟勋爵     海薇玛夫人     谢贝蕾小姐     拐增伤    血   双爆                                   
    0命  精1专武              29981       16262          41688         75    39883   100/233
    0命  精1狼牙              24644       13367          34267         75    37114   91/204     e 8暴击
    0命  精5狼牙              27228       14768          37861         75    38631   81/211     e 16暴击
    0命  精5腐蚀              22057       11964          30670         75    35597   80/184    多45.9充能 e12暴击
    召唤物攻击间隔             2.9s        1.19s           4.8s
    1命  精1专武              32228       17481          44813         100
    2命  精1专武              37296       20229          51860         100                2命按照+40%血算 
    3命  精1专武              39792       21583          55331         124
    5命  精1专武              46986       25477          65307         124
    
*/

let cid = "units"
let count_kit = 0;
let combination = getCombination(Array(5*CONFIG.chance + 1).fill().map((_,i)=>i), CONFIG.chance, Object.entries(tmp))
let clips_initial_data = calc_clips_initial()
let fs = require("fs");

let conns = 0 // ming zuo
let selectIndex = 3;

// 生水爆 751238  生水生 733047  生生爆 774846 sss 739298

calc(combination);
function calc(clipSecondData) {
    let charactersDmg = [];
    clipSecondData = clipSecondData.map(clipSecondDataItem => {
        let clipSecond = {}
        clipSecond.des = clipSecondDataItem;
        clipSecond.data = {} 
        for (let secondKey in clipSecond.des) {
            let count =  clipSecond.des[secondKey]
            clipSecond.data[secondKey] = count * CLIPDATA[secondKey]
        }
        return clipSecond
    })
    
    Object.values(WEAPONS).forEach(weapon => {
        if(charaters[cid].weapontype && weapon.weapontype != charaters[cid].weapontype && weapon.weapontype!="all") {return}
        charactersDmg.push(getDMG([charaters[cid],weapon,clips_initial_data,{...CONFIG.clips_main}], clipSecondData, (data,second) => {
            count_kit++;
            data = objValueAdd([data, ...CONFIG.buffs]);
            
            if(weapon.skill) { weapon.skill(data); }
            if( conns >= 2) {
                data.hpRate += 40
            }
            data.hp = data.hp*(1 + (data.hpRate||0)/100) + data.fixedHp;
            let rea = { reaction:data.reaction, reactionQ:CONFIG.reactionK, reactionDmgAdd:data.reactionDmgAdd || 0 }
            
            let qifen = 300;
            if( conns >= 1) {
                qifen = 400
            }
            

            let eDmg = data.hp/1000*0.7
            if(eDmg > 28) { eDmg = 28 }
            let treatSpeed = data.hp/1000*0.4
            if(treatSpeed > 16) { treatSpeed = 16 }
            
            let qRate = [0.2053, 0.25];
            if(conns >= 3) {
                qRate = [0.2424, 0.31];
            }
            let qzenshang = qRate[1] * qifen
            data.dmgRate += qzenshang
            let QDmg = getDmg({ data:{...data, dmgRate:data.dmgRate+(data.qdmgRate||0),dmgZhi: data.hp*qRate[0]}, rate:0}).qw * reduceResistanceK(10-(data.jk||0)) * lvSuppressK(CONFIG.your_lv, CONFIG.enemy_lv, 0); //
            
            let eRate = [0.1416, 0.1073, 0.0582, 0.1492, 0.0864, 1016.97];
            if(conns >= 5) {
                eRate = [0.1671 ,0.1267, 0.0687, 0.1761, 0.102, 1271.23];
            }

            let EDmg = getDmg({
                data: {
                    ...data,
                    criticalRate:data.criticalRate + (data.ecriticalRate||0),
                    dmgZhi: data.hp * eRate[0],
                    dmgRate: data.dmgRate + (data.eDmg || 0) + (data.eDmgAdd || 0)
                }
                , rate: 0
            }).qw * reduceResistanceK(10 - (data.jk || 0)) * lvSuppressK(CONFIG.your_lv, CONFIG.enemy_lv, 0); //

            let E1Dmg = getDmg({
                data: {
                    ...data,
                    criticalRate:data.criticalRate + (data.ecriticalRate||0),
                    dmgZhi: data.hp * eRate[1] * 1.4,
                    dmgRate: data.dmgRate + eDmg + (data.eDmg || 0)+ (data.eDmgAdd || 0)
                }
                , rate: 0
            }).qw * reduceResistanceK(10 - (data.jk || 0)) * lvSuppressK(CONFIG.your_lv, CONFIG.enemy_lv, 0); //
            let E2Dmg = getDmg({
                data: {
                    ...data,
                    criticalRate:data.criticalRate + (data.ecriticalRate||0),
                    dmgZhi: data.hp * eRate[2] * 1.4,
                    dmgRate: data.dmgRate + eDmg + (data.eDmg || 0)+ (data.eDmgAdd || 0)
                }
                , rate: 0
            }).qw * reduceResistanceK(10 - (data.jk || 0)) * lvSuppressK(CONFIG.your_lv, CONFIG.enemy_lv, 0); //
            let E3Dmg = getDmg({
                data: {
                    ...data,
                    criticalRate:data.criticalRate + (data.ecriticalRate||0),
                    dmgZhi: data.hp * eRate[3] * 1.4,
                    dmgRate: data.dmgRate + eDmg + (data.eDmg || 0)+ (data.eDmgAdd || 0)
                }
                , rate: 0
            }).qw * reduceResistanceK(10 - (data.jk || 0)) * lvSuppressK(CONFIG.your_lv, CONFIG.enemy_lv, 0); //
            let treat = data.hp * eRate[4] + eRate[5]




            let point = QDmg * 1 + EDmg*1 + E1Dmg*5 + E2Dmg*12 + E3Dmg*3 ;   // 
            
            return {point, data, second, dmg:{QDmg, EDmg, E1Dmg, E2Dmg, E3Dmg, qzenshang, treat}}
        }))
    })
    
    charactersDmg.sort((a,b)=>{
        return (b.point)-(a.point);
    });

    let sortf = JSON.parse(fs.readFileSync("./sort.js").toString()) 
    let choose = charactersDmg[selectIndex];
    console.log(choose);
    let name = choose.data.name
    let keys = "_"+choose.data.weaponname+"_6命无拐饰金之梦毕业"
    let sortfData = {key: name+keys, point:choose.point, dmg:JSON.parse(JSON.stringify(choose.dmg))}
    if(sortfData.point && sortfData.point > 0) {
        let org = sortf.findIndex(item3 => item3.key == sortfData.key)
        if(org >= 0){
            sortf[org] = sortfData
        } else {
            sortf.push(sortfData)
        }
        sortf.sort((b,a) => a.point-b.point)
        // fs.writeFileSync("./sort.js", JSON.stringify(sortf))
    }
    fs.writeFileSync("./ret.js", "let a = " + JSON.stringify(choose))
    console.log(charactersDmg.map((v, n)=>{
        return  `(${n})得分: ${v.data.weaponname} : ${v.point.toFixed(0)}`
    }));
    console.log(count_kit);
}

function getDMG(dataarr, clipSecond, getRet){
    clipSecond = clipSecond.map(second => {
        let panel = objValueAdd([...dataarr, second.data]);
        return  getRet(panel, second)
    })
    clipSecond.sort((b,a)=> a.point-b.point)
    return clipSecond[0]
}

function calc_clips_initial () {
    let clips = CONFIG.clips_initial.map(v => {
        let tmp = {};
        v.forEach(v2 => {
            tmp[v2] = CLIPDATA[v2]
        })
        return tmp
    })
    let data = {}
    clips.forEach(item => {
        for (const key in item) {
            data[key] = data[key]? (data[key]+item[key]) : item[key]
        }
    })
    return data
}
function getCombination (arr, chance, entrys) {
    let num = 5
    var r = [];
    (function f(t, a, n) {
        if (n === 0) {
            if(t.reduce((a1,b1) => a1+b1) !== chance * 5){return}
            let ret = {}
            for (let i in t) {
                if(t[i] > entrys[i][1]*chance){return}
                ret[entrys[i][0]] = t[i]
            }
            r.push(ret)
            return ;
        }
        for (var i = 0, l = a.length; i < l; i++) {
            f(t.concat(a[i]), a, n - 1);
        }
    })([], arr, num);
    return r;
}